import React, {
  FC,
  ReactNode,
  useContext,
  useState,
  useCallback,
  useEffect,
} from 'react';
import { FormStoreContext } from './config';

export interface IProps {
  name?: string;
  label?: string;
  children?: ReactNode;
}

// 从onChange事件中获取表单值，这里主要应对checkbox的特殊情况
function getValueFromEvent(...args: any[]) {
  const e = args[0];
  return e && e.target
    ? e.target.type === 'checkbox'
      ? e.target.checked
      : e.target.value
    : e;
}

const Field: FC<IProps> = ({ name, label, children }) => {
  const store = useContext(FormStoreContext);
  const [value, setValue] = useState('');
  const [error, setError] = useState('');

  useEffect(() => {
    if (!name || !store) return;
    store.subscribe((n) => {
      // 当前name的数据发生了变动，获取数据并重新渲染
      if (n === name || n === '*') {
        setValue(store.get(name));

        setError(store.error(name));
      }
    }, name);
  }, [name, store]);

  const onChange = useCallback(
    (value) => {
      name && store && store.set(name, getValueFromEvent(value));
    },
    [name, store]
  );

  let child = children;
  if (React.isValidElement(children)) {
    const p = { value, onChange };
    child = React.cloneElement(children, p);
  }

  return (
    <div className="form">
      <label className="form__label">{label}</label>
      <div className="form__content">
        <div className="form__control">{child}</div>
        <div className="form__message">{error}</div>
      </div>
    </div>
  );
};

export default Field;
